import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(home: SnapAppBar2Widget()));
}

class SnapAppBar2Widget extends StatefulWidget {
  const SnapAppBar2Widget({Key? key}) : super(key: key);

  @override
  _SnapAppBar2WidgetState createState() => _SnapAppBar2WidgetState();
}

class _SnapAppBar2WidgetState extends State<SnapAppBar2Widget> {
  late SliverOverlapAbsorberHandle handle;

  void onOverlapChanged() {
    print(handle.layoutExtent);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (context, innerBoxIsScrolled) {
          handle = NestedScrollView.sliverOverlapAbsorberHandleFor(context);
          //添加监听前先移除旧的
          handle.removeListener(onOverlapChanged);
          //overlap长度发生变化时打印
          handle.addListener(onOverlapChanged);
          return <Widget>[
            SliverOverlapAbsorber(
              handle: handle,
              sliver: SliverAppBar(
                floating: true,
                snap: true,
                // pinned: true,  // 放开注释，然后看日志
                expandedHeight: 200,
                flexibleSpace: FlexibleSpaceBar(
                  background: Image.asset(
                    "assets/images/avatar.png",
                    fit: BoxFit.cover,
                  ),
                ),
                forceElevated: innerBoxIsScrolled,
              ),
            ),
          ];
        },
        body: LayoutBuilder(
          builder: (context, cons) {
            return CustomScrollView(
              slivers: <Widget>[
                SliverOverlapInjector(handle: handle),
                buildSliverList(100),
              ],
            );
          },
        ),
      ),
    );
  }

  @override
  void dispose() {
    handle.removeListener(onOverlapChanged);
    super.dispose();
  }
}

// 构建固定高度的SliverList，count为列表项属相
Widget buildSliverList([int count = 5]) {
  return SliverFixedExtentList(
    itemExtent: 50,
    delegate: SliverChildBuilderDelegate(
      (context, index) {
        return ListTile(title: Text('$index'));
      },
      childCount: count,
    ),
  );
}
